function Building(id, startTile)
{
    this.id = id;

    this.startTile = startTile;

    this.pos = {
        row:    findRowCol(this.startTile).row,
        col:    findRowCol(this.startTile).col
    };

    this.heroId = null;

    this.stock = [];

    this.tilesList = [];
    this.img = null;
}

function initBuilding(building, buildingTile) {
    var newBuilding = null;

    switch(building.type) {
        case BUILDINGS.SILO:  newBuilding = new Silo(-1, buildingTile); break;
        case BUILDINGS.BARN:    newBuilding = new Barn(-1, buildingTile); break;
        case BUILDINGS.COLDSTORAGE:   newBuilding = new ColdStorage(-1, buildingTile); break;
        default: break;
    }

    newBuilding.heroId = building.heroId;
    newBuilding.stock = building.stock;
    newBuilding.capacity = building.capacity;
    newBuilding.tilesList.push(newBuilding.startTile);

    switch(newBuilding.type) {
        case(BUILDINGS.SILO):
            break;

        case(BUILDINGS.BARN):
            var refCoords = findRowCol(newBuilding.startTile);
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row, refCoords.col - 1));
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col - 1));
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col));
            break;

        case(BUILDINGS.COLDSTORAGE):
            var refCoords = findRowCol(newBuilding.startTile);
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row, refCoords.col - 1));
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col - 1));
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col));
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row + 2, refCoords.col - 1));
            newBuilding.tilesList.push(findTileByRowCol(refCoords.row + 2, refCoords.col));
            break;

        default:
            break;
    }

    for(var tile = 0; tile < newBuilding.tilesList.length; tile++) {
        newBuilding.tilesList[tile].setBuilding(newBuilding);
    }

    return newBuilding;
}

Building.prototype.asSimpleObject = function() {
    return {
        id:     this.id,
        heroId: this.heroId,
        stock:  this.stock,
        type:   this.type,
        pos:    this.pos,
        capacity: this.capacity
    }
}

Building.prototype.getInfos = function() {
    selectedBuilding = this;
    var infosText = '<br />Building stats :';

    infosText += '<br /> Capacity : ' + this.capacity;
    if(this.stock.length == 0) {
        infosText += '<br/>(empty)';
        return infosText;
    }

    infosText += ', contains :';

    for(var h in this.stock) {
        var strType = convertTypeToStr(this.stock[h].type);
        var units = this.stock[h].units;
        var price = this.stock[h].price;

        infosText += '<br/> '+strType+' (x'+units+') : '+price+' golds';
    }

    infosText += '<br/><br/><button onclick="sellFromBuilding()">Sell all goods</button>';
    return infosText;
}

Building.prototype.addToStock = function(crop) {
     if(this.capacity < crop.productivity) {
         gameMsg('Not enough room in this building !');
         return false;
     }

    var harvest = {
        storability:crop.storability,
        type:       crop.type,
        price:      crop.seedPrice,
        units:      crop.productivity
    };

    this.stock.push(harvest);
    this.capacity -= crop.productivity;

    return true;
}

Building.prototype.clearStock = function() {
    this.stock.splice(0,this.stock.length);
}

Building.prototype.setupBuilding = function () {
    this.heroId = hero.id;

    this.tilesList.push(this.startTile);
    switch(this.type) {

        case(BUILDINGS.SILO):
            break;

        case(BUILDINGS.BARN):
            var refCoords = findRowCol(this.startTile);
            this.tilesList.push(findTileByRowCol(refCoords.row, refCoords.col - 1));
            this.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col - 1));
            this.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col));
            break;

        case(BUILDINGS.COLDSTORAGE):
            var refCoords = findRowCol(this.startTile);
            this.tilesList.push(findTileByRowCol(refCoords.row, refCoords.col - 1));
            this.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col - 1));
            this.tilesList.push(findTileByRowCol(refCoords.row + 1, refCoords.col));
            this.tilesList.push(findTileByRowCol(refCoords.row + 2, refCoords.col - 1));
            this.tilesList.push(findTileByRowCol(refCoords.row + 2, refCoords.col));
            break;

        default:
            break;
    }

    for(var tile = 0; tile < this.tilesList.length; tile++) {
        this.tilesList[tile].setBuilding(this);
    }

    cl_building_update(this.asSimpleObject());
    hero.addBuilding(this.asSimpleObject());
    this.drawBuilding();
}

//Renvoi une list de tile concernées par le placement d'un type de bâtiment
//et gère le débordement d'un bâtiment par rapport aux limites de la map
Building.prototype.getTilesUnder = function(startTile) {
    var tileList = [];
    tileList.push(startTile);

    switch(this.type) {

        case(BUILDINGS.SILO):
            break;

        case(BUILDINGS.BARN):
            var refCoords = findRowCol(startTile);
            var tryCoord = refCoords.col - 1;
            if(tryCoord < 0)
                tileList.push("OVERFLOW_UP");
            else
                tileList.push(findTileByRowCol(refCoords.row, refCoords.col - 1));

            tryCoord = refCoords.row + 1;
            if(tryCoord >= grid.width)
                tileList.push("OVERFLOW_RIGHT");
            else
                tileList.push(findTileByRowCol(refCoords.row + 1, refCoords.col - 1));

            tileList.push(findTileByRowCol(refCoords.row + 1, refCoords.col));
            break;

        case(BUILDINGS.COLDSTORAGE):
            var refCoords = findRowCol(startTile);

            var tryCoord = refCoords.col - 1;
            if(tryCoord < 0)
                tileList.push("OVERFLOW_UP");
            else
                tileList.push(findTileByRowCol(refCoords.row, refCoords.col - 1));

            tryCoord = refCoords.row + 1;
            if(tryCoord >= grid.width)
                tileList.push("OVERFLOW_RIGHT");
            else
                tileList.push(findTileByRowCol(refCoords.row + 1, refCoords.col - 1));

            tileList.push(findTileByRowCol(refCoords.row + 1, refCoords.col));

            tryCoord = refCoords.row + 2;
            if(tryCoord >= grid.width)
                tileList.push("OVERFLOW_RIGHT");
            else
                tileList.push(findTileByRowCol(refCoords.row + 2, refCoords.col - 1));

            tileList.push(findTileByRowCol(refCoords.row + 2, refCoords.col));
            break;

        default:
            break;
    }

    return tileList;
}

Building.prototype.drawBuilding = function() {
    switch(this.type) {
        case(BUILDINGS.SILO):
            c.drawImage(this.img,
                this.tilesList[0].x + camera.x,
                this.tilesList[0].y + camera.y);
            break;

        case(BUILDINGS.BARN):
        case(BUILDINGS.COLDSTORAGE):
            c.drawImage(this.img,
                this.tilesList[0].x + camera.x,
                this.tilesList[1].y + camera.y);
            break;

        default:
            break;
    }
}

function Silo(id, startTile) {
    Building.call(this, id, startTile);

    this.img = b_siloImg;
    this.type = BUILDINGS.SILO;

    this.cost = 100;
    this.capacity = 50;
    this.goods = null;
}
    Silo.prototype = new Building();
    Silo.prototype.constructor = Silo;


function Barn(id, startTile) {
    Building.call(this, id, startTile);

    this.img = b_barnImg;
    this.type = BUILDINGS.BARN;

    this.cost = 400;
    this.capacity  = 250;
    this.goods = null;
}
    Barn.prototype = new Building();
    Barn.prototype.constructor = Barn;


function ColdStorage(id, startTile) {
    Building.call(this, id, startTile);

    this.img = b_coldstorageImg;
    this.type = BUILDINGS.COLDSTORAGE;

    this.cost = 600;
    this.capacity = 300;
    this.goods = null;
}
    ColdStorage.prototype = new Building();
    ColdStorage.prototype.constructor = ColdStorage;

    ColdStorage.prototype.powerCostTimer = function() {
        setInterval(function() {
            hero.updateGolds(-1);
        }, 1000);
    }